package com.example.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import java.util.Calendar;


/**
 * ******************************
 *
 * @AUTHOR Jack_LeiLei
 * @CREATETIME 2019/8/11
 * @DESCRIBE 文字时钟view
 * <p>
 * ******************************
 */
public class TextClockView extends View {
    private Paint mPaint;
    private Paint mHelperPaint;
    private float mWidth;
    private float mHeight;
    private float mHourR;
    private float mMinuteR;
    private float mSecondR;
    private float mHourDeg;
    private float mMinuteDeg;
    private float mSecondDeg;
    private ValueAnimator mAnimator;


    public TextClockView(Context context) {
        super(context, null);
    }

    public TextClockView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
        init();
    }


    private void init() {
        //处理动画，声明全局的处理器
        mAnimator = ValueAnimator.ofFloat(6f, 0f);//由6降到1
        mAnimator.setDuration(150);
        mAnimator.setInterpolator(new LinearInterpolator());//插值器设为线性
        mPaint = new Paint();
        mPaint.setColor(Color.WHITE);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);

        mHelperPaint = new Paint();
        mHelperPaint.setColor(Color.RED);
        mHelperPaint.setAntiAlias(true);
        mHelperPaint.setStyle(Paint.Style.FILL);
        doInvalidate();
    }

    //在onLayout方法中计算view去除padding后的宽高
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        mHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
        //后文会涉及到
        //统一用View宽度*系数来处理大小，这样可以联动适配样式
        mHourR = mWidth * 0.143f;
        mMinuteR = mWidth * 0.35f;
        mSecondR = mWidth * 0.35f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (canvas == null) return;
        canvas.drawColor(Color.BLACK);//填充背景
        canvas.save();
        canvas.translate(mWidth / 2, mHeight / 2);//原点移动到中心

        //绘制各元件
        drawCenterInfo(canvas);
        drawHour(canvas, mHourDeg);
        drawMinute(canvas, mMinuteDeg);
        drawSecond(canvas, mSecondDeg);
        //辅助线
        canvas.drawLine(0f, 0f, mWidth, 0f, mHelperPaint);
        canvas.restore();
    }

    /**
     * 绘制圆中信息
     */
    private void drawCenterInfo(Canvas canvas) {
        Calendar mCalendar = Calendar.getInstance();
        int hour = mCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = mCalendar.get(Calendar.MINUTE);
        String minutes = "";
        if (minute < 10) {
            minutes = "0" + minute;
        } else {
            minutes = minute + "";
        }
        mPaint.setTextSize(mHourR * 0.4f);
        mPaint.setAlpha(255);
        mPaint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(hour + ":" + minutes, 0f, getBottomedY(), mPaint);

        //绘制月份、星期
        int year = (mCalendar.get(Calendar.YEAR));
        int month = (mCalendar.get(Calendar.MONTH) + 1);
        String months = "";
        if (month < 10) {
            months = "0" + month;
        } else {
            months = month + "";
        }
        int day = mCalendar.get(Calendar.DAY_OF_MONTH);
        int dayOfWeek = mCalendar.get(Calendar.DAY_OF_WEEK) - 1;
        mPaint.setTextSize(mHourR * 0.16f);
        mPaint.setAlpha(255);
        mPaint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(year + "." + months + "." + day + "星期" + toText(dayOfWeek), 0f, getToppedY(), mPaint);
    }


    /**
     * 绘制小时
     */
    private void drawHour(Canvas canvas, float degrees) {
        mPaint.setTextSize(mHourR * 0.16f);
        //处理整体旋转
        canvas.save();
        canvas.rotate(degrees);

        for (int i = 0; i < 12; i++) {
            canvas.save();
            //从x轴开始旋转，每30°绘制一下几点，12次可以绘制完成
            float iDeg = 360 / 12f * i;
            canvas.rotate(iDeg);
            if ((iDeg + degrees) == 0f) {
                mPaint.setAlpha(255);
            } else {
                mPaint.setAlpha((int) (0.6f * 255));
            }
            mPaint.setTextAlign(Paint.Align.LEFT);
            canvas.drawText(toText((i + 1)) + "点", mHourR, getCenteredY(), mPaint);
            canvas.restore();
        }
        canvas.restore();
    }

    /**
     * 绘制分钟
     */
    private void drawMinute(Canvas canvas, float degrees) {
        mPaint.setTextSize(mHourR * 0.16f);
        //处理整体旋转
        canvas.save();
        canvas.rotate(degrees);
        for (int i = 0; i < 60; i++) {
            canvas.save();
            float iDeg = 360 / 60f * i;
            canvas.rotate(iDeg);
            if ((iDeg + degrees) == 0f) {
                mPaint.setAlpha(255);
            } else {
                mPaint.setAlpha((int) (0.6f * 255));
            }
            mPaint.setTextAlign(Paint.Align.RIGHT);
            if (i < 59) {
                canvas.drawText(toText((i + 1)) + "分", mMinuteR, getCenteredY(), mPaint);
            }
            canvas.restore();
        }
        canvas.restore();
    }


    /**
     * 绘制秒
     */
    private void drawSecond(Canvas canvas, float degrees) {
        mPaint.setTextSize(mHourR * 0.16f);
        //处理整体旋转
        canvas.save();
        canvas.rotate(degrees);
        for (int i = 0; i < 60; i++) {
            canvas.save();
            float iDeg = 360 / 60f * i;
            canvas.rotate(iDeg);
            if ((iDeg + degrees) == 0f) {
                mPaint.setAlpha(255);
            } else {
                mPaint.setAlpha((int) (0.6f * 255));
            }
            mPaint.setTextAlign(Paint.Align.LEFT);
            if (i < 59) {
                canvas.drawText(toText((i + 1)) + "秒", mSecondR, getCenteredY(), mPaint);
            }
            canvas.restore();
        }
        canvas.restore();
    }

    /**
     * 扩展获取绘制文字时在x轴上 垂直居中的y坐标
     */
    private float getCenteredY() {
        return mPaint.getFontSpacing() / 2 - mPaint.getFontMetrics().bottom;
    }

    /**
     * 扩展获取绘制文字时在x轴上 贴紧x轴的上边缘的y坐标
     */
    private float getBottomedY() {
        return -mPaint.getFontMetrics().bottom;
    }

    /**
     * 扩展获取绘制文字时在x轴上 贴近x轴的下边缘的y坐标
     */
    private float getToppedY() {
        return -mPaint.getFontMetrics().ascent;
    }


    String mArray[] = {"日",
            "一",
            "二",
            "三",
            "四",
            "五",
            "六",
            "七",
            "八",
            "九",
            "十"};

    private String toText(int it) {
        String result = "";
        char iArr[] = String.valueOf(it).toCharArray();
        //处理 10，11，12.. 20，21，22.. 等情况
        if (iArr.length > 1) {
            if (iArr[0] != 1) {
                int index = Integer.valueOf(String.valueOf(iArr[0]));
                result += mArray[index];
            }
            result += "十";
            if (iArr[1] > 0) {
                int index = Integer.valueOf(String.valueOf(iArr[1]));
                result += mArray[index];
            }
        } else {
            int index = Integer.valueOf(String.valueOf(iArr[0]));
            result = mArray[index];
        }
        return result;
    }

    float hd = 0;
    float md = 0;
    float sd = 0;

    /**
     * 开始绘制
     */
    public void doInvalidate() {
        Calendar mCalendar = Calendar.getInstance();
        int hour = mCalendar.get(Calendar.HOUR);
        final int minute = mCalendar.get(Calendar.MINUTE);
        final int second = mCalendar.get(Calendar.SECOND);
        mHourDeg = -360 / 12f * (hour - 1);
        mMinuteDeg = -360 / 60f * (minute - 1);
        mSecondDeg = -360 / 60f * (second - 1);

        //记录当前角度，然后让秒圈线性的旋转6°
        hd = mHourDeg;
        md = mMinuteDeg;
        sd = mSecondDeg;

        //处理动画
        mAnimator.removeAllUpdateListeners();//需要移除当前的监听
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float av = (float) animation.getAnimatedValue();
                if (minute == 0 && second == 0) {
                    mHourDeg = hd + av * 5;//时圈旋转角度是分秒的5倍，线性的旋转30°
                }
                if (second == 0) {
                    mMinuteDeg = md + av;//线性的旋转6°
                }
                mSecondDeg = sd + av;//线性的旋转6°
                invalidate();
            }
        });
        mAnimator.start();
    }
}
